package com.sx.pipeline.ui.map

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.Point
import android.view.MotionEvent
import com.amap.api.maps.AMap
import com.amap.api.maps.model.*
import com.luck.picture.lib.utils.DensityUtil
import com.sx.pipeline.R
import com.sx.pipeline.ui.map.entity.DrawLatLng
import com.sx.pipeline.ui.map.tools.CommonUtils
import com.sx.pipeline.ui.map.tools.DrawMapUtils
import kotlin.math.pow
import kotlin.math.sqrt

/**
 * @Author: YY
 * @Date: 2022/4/20
 * @Description: 区域绘制
 */
@SuppressLint("StaticFieldLeak")
object DistrictDrawHelper {

    // 全局上下文
    private lateinit var mContext: Context

    // 是否绘制完毕
    private var hasDrawFinish = false
    // 是否按压绘制
    private var isDrawPress = false
    // 坐标系对象
    private lateinit var mLatLng: LatLng
    // 地图Map
    private lateinit var aMap: AMap
    // 绘制线
    private lateinit var polyline: Polyline
    // 绘制多边形
    private lateinit var polygon: Polygon
    // 绘制点列表
    private val pointList: MutableList<DrawLatLng> = mutableListOf()
    // 圆点 Marker列表
    private val circleList: MutableList<Marker> = mutableListOf()
    // 距离集合
    private val distanceMap: MutableMap<Int, Int> = mutableMapOf()

    // 默认圆大小
    private var circleDefault: Int = 0
    // 移动位置
    private var movePosition = -1
    // 是否第一个点
    private var isFirstPoint = false
    // 是否最后一个点
    private var isLastPoint = false
    // 按下和移动的x轴和y轴
    private var xDown: Int = 0
    private var yDown: Int = 0
    private var xMove: Int = 0
    private var yMove: Int = 0

    /**
     * 绘制-点
     * @param latLng  坐标系
     * @param aMap   地图图层
     * 可在 [onMapClick()] 事件中调用
     */
    fun drawPoints(context: Context, latLng: LatLng, aMap: AMap) {
        this.mContext = context
        this.aMap = aMap
        if (!isDrawPress) {
            // 如果没有绘制完成
            if (!hasDrawFinish) {
                if (pointList.size == 0) {
                    //画个大圆圈
                    val myLatLng = DrawLatLng(latLng, true)
                    circleList.add(drawBigCircle(latLng, 0))
                    pointList.add(myLatLng)
                    return
                }

                //再画大圈圈
                circleList.add(drawBigCircle(latLng, circleList.size))
                pointList.add(DrawLatLng(latLng, true))

                // 两点连接起来
                drawLine()
                return
            }
        }
    }

    /**
     * 绘制区域
     * 可在 [onMarkerClick()] 事件中调用
     */
    fun drawDistrict(marker: Marker) {
        val firstLatitude = pointList[0].latLng.latitude
        val firstLongitude = pointList[0].latLng.longitude

        if (!hasDrawFinish
            && marker.position.latitude == firstLatitude
            && marker.position.longitude == firstLongitude
        ) {
            drawPolygon()
            hasDrawFinish = true
        }
    }

    /**
     * 上一步
     */
    fun lastStep() {
        if (hasDrawFinish) {
            //已完成
            circleList[circleList.size - 1].remove()
            circleList.removeAt(circleList.size - 1)
            pointList.removeAt(pointList.size - 1)
            hasDrawFinish = false
        } else {
            //还没完成
            if (circleList.size > 0) {
                //删除最后一个
                circleList[circleList.size - 1].remove()
                circleList.removeAt(circleList.size - 1)
                pointList.removeAt(pointList.size - 1)
                if (circleList.size > 1) {
                    //删除倒数第二个
                    circleList[circleList.size - 1].remove()
                    circleList.removeAt(circleList.size - 1)
                    pointList.removeAt(pointList.size - 1)
                }
            }
        }
        drawLine()
    }


    /**
     * 清除绘制
     * [onDestroy()] 中或其他事件中调用
     */
    fun clearDraw() {
        for (i in circleList.indices) {
            circleList[i].remove()
        }
        circleList.clear()
        pointList.clear()

        if (this::polyline.isInitialized) {
            polyline.remove()
        }
        if (this::polygon.isInitialized) {
            polygon.remove()
        }

        hasDrawFinish = false
    }

    /**
     * 处理onTouch事件
     */
    fun handleTouchEvent(ev: MotionEvent) {
        circleDefault = DensityUtil.dip2px(mContext, 20.0f)
        if (pointList.size <= 2) {
            return
        }
        try {
            when {
                MotionEvent.ACTION_DOWN == ev.action -> {
                    // 按下
                    xDown = ev.x.toInt()
                    yDown = ev.y.toInt()
                    xMove = ev.x.toInt()
                    yMove = ev.y.toInt()
                }
                MotionEvent.ACTION_MOVE == ev.action -> {
                    // 移动
                    if (isDrawPress) {
                        handlePressEvent(ev)
                    } else {
                        xMove = ev.x.toInt()
                        yMove = ev.y.toInt()
                        val distance = sqrt((xDown - xMove).toDouble().pow(2.0)
                                + (yDown - yMove).toDouble().pow(2.0))
                        if (distance > DensityUtil.dip2px(mContext, 10.0f)) {
                            isDrawPress = true
                            handleDownTouchEvent(ev)
                        }
                    }
                }
                MotionEvent.ACTION_UP == ev.action -> {
                    // 抬起
                    handleMoveTouchEvent()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    /**
     * 滑动事件
     * @param ev
     */
    private fun handlePressEvent(ev: MotionEvent) {
        if (movePosition == -1) {
            return
        }
        if (hasDrawFinish) {
            // 处理绘制完成的滑动
            handleFinishPress(ev)
        } else {
            // 处理未绘制完成的滑动
        }
    }

    /**
     * 已经完成的
     */
    private fun handleFinishPress(ev: MotionEvent) {
        val latLng = aMap.projection.fromScreenLocation(Point(ev.x.toInt(), ev.y.toInt()))
        handlePoint(latLng)
    }

    /**
     * 处理滑动的点
     */
    private fun handlePoint(latLng: LatLng) {
        // 移除原来的
        circleList[movePosition].remove()
        circleList.removeAt(movePosition)
        pointList.removeAt(movePosition)
        // 绘制新的
        circleList.add(movePosition, drawBigCircle(latLng, movePosition))
        pointList.add(movePosition, DrawLatLng(latLng, true))
        // 绘制矩形
        drawPolygon()
    }


    /**
     * 处理按下触摸事件
     */
    private fun handleDownTouchEvent(ev: MotionEvent) {
        distanceMap.clear()
        for (i in pointList.indices) {
            val point = aMap.projection.toScreenLocation(pointList[i].latLng)
            val distance = sqrt((ev.x - point.x).toDouble().pow(2.0)
                        + (ev.y - point.y).toDouble().pow(2.0)).toInt()
            distanceMap[i] = distance
        }
        val arr: IntArray = CommonUtils.getKeyOfMinValue(distanceMap)
        if (arr[1] < circleDefault) {
            isDrawPress = true
            aMap.uiSettings.setAllGesturesEnabled(false)
            movePosition = arr[0]
        }
    }


    /**
     * 滑动结束
     */
    private fun handleMoveTouchEvent() {
        isDrawPress = false
        movePosition = -1
        isFirstPoint = false
        isLastPoint = false
        aMap.uiSettings.setAllGesturesEnabled(true)
        aMap.uiSettings.isRotateGesturesEnabled = false //关闭旋转手势
        aMap.uiSettings.isTiltGesturesEnabled = false //关闭倾斜手势
    }

    /**************************** 绘制Marker ***********************************/

    /**
     * 画大圆圈
     */
    @SuppressLint("InflateParams")
    private fun drawBigCircle(latLng: LatLng, position: Int): Marker {
        return this.aMap.addMarker(MarkerOptions()
            .position(latLng)
            .anchor(0.5f, 0.5f)
            .title(position.toString())
            .icon(BitmapDescriptorFactory.fromView((mContext as Activity).layoutInflater.inflate(
                R.layout.view_map_marker_big_circle, null))))
    }


    /**
     * 绘制线，把点连起来
     */
    private fun drawLine() {
        if (this::polyline.isInitialized) {
            polyline.remove()
        }
        if (this::polygon.isInitialized) {
            polygon.remove()
        }
        if (pointList.size > 0) {
            polyline = this.aMap.addPolyline(PolylineOptions().addAll(DrawMapUtils.drawLatLngToLatLng(pointList))
                    .width(2f).color(Color.parseColor("#0188FF")).zIndex(999f))  // 线颜色
        }
    }

    /**
     * 绘制多边形
     */
    private fun drawPolygon() {
        if (pointList.size <= 2) {
            return
        }

        if (this::polyline.isInitialized) {
            polyline.remove()
        }
        if (this::polygon.isInitialized) {
            polygon.remove()
        }

        // 多边形参数对象
        val polygonOptions = PolygonOptions()
        // 添加 多边形的每个顶点（顺序添加）
        for (i in pointList.indices) {
            polygonOptions.add(pointList[i].latLng)
        }
        val hasOverlap: Boolean = DrawMapUtils.checkDrawOverlap(pointList, this.aMap)
        if (hasOverlap) {
            //说明重合了
            polygonOptions.strokeWidth(2f)
                .strokeColor(Color.parseColor("#ffffff")) // 边框颜色
                .fillColor(Color.parseColor("#80FF0000")) // 多边形的填充色
        } else {
            polygonOptions.strokeWidth(2f)
                .strokeColor(Color.parseColor("#ffffff")) // 边框颜色
                .fillColor(Color.parseColor("#66000000")) // 多边形的填充色
        }
        polygon = this.aMap.addPolygon(polygonOptions.zIndex(100f))
    }

    /**
     * 获取 点列表数量
     */
    fun getPointListSize(): Int {
        return pointList.size
    }

    /**
     * 获取 点列表
     */
    fun getPointList(): MutableList<DrawLatLng> {
        return pointList
    }

    /**
     * 是否 绘制完成标记位
     */
    fun getHasDrawFinish(): Boolean {
        return hasDrawFinish
    }
}